<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>光弹效应自动测试系统</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <link rel="stylesheet" href="style.css"> 
</head>

<body>
  <h1>光弹效应自动测试系统</h1>

  <div class="main">
    <!-- 左侧 -->
    <div class="left-panel">
      <!-- LED 模块 -->
      <div class="box">
        <h3>LED 指示灯状态</h3>
        <div>
          <span class="led" id="led1"></span>
          <span class="led" id="led2"></span>
          <span class="led" id="led3"></span>
          <span class="led" id="led4"></span><br/><br/>
          <button onclick="toggleLEDs()">变亮/变暗</button>
        </div>
      </div>
  
      <!-- 厚度模块 -->
      <div class="box">
        <h3>厚度值（单位 mm）</h3>

      <!-- 静态说明 -->
      <div style="margin-bottom: 6px;">薄膜厚度 t</div>

      <!-- 输入区域 -->
      <div class="thickness-row">
        <label for="d1">拉伸前厚度 t1:</label>
        <input type="number" id="d1" value="1.00" step="0.01">
        <label for="d2">拉伸后厚度 t2:</label>
        <input type="number" id="d2" value="0.90" step="0.01">
      </div>

      <div class="result-box">厚度变化 Δt = <span id="delta">?</span></div>
        <button onclick="calculateDelta()">计算厚度变化 Δt</button>
    </div>

    <!-- 动镜移动距离模块 -->
    <div class="box">
      <h3>动镜移动距离（单位 mm）</h3>

      <!-- 静态说明 -->
      <div style="margin-bottom: 6px;">动镜距离 d</div>

      <!-- 输入区域 -->
      <div class="thickness-row">
        <label for="d1_dist">移动前距离 d1:</label>
        <input type="number" id="d1_dist" value="5.00" step="0.01">
        <label for="d2_dist">移动后距离 d2:</label>
        <input type="number" id="d2_dist" value="5.50" step="0.01">
      </div>

      <div class="result-box">距离变化 Δd = <span id="delta_dist">?</span></div>
      <button onclick="calculateDistanceDelta()">计算动镜移动距离 Δd</button>
    </div>

      <!-- 折射率模块 -->
      <div class="box">
        <h3>折射率</h3>
        <div>折射率计算公式：n = Δd / Δt + 1</div><br>
        <div class="result-box">折射率 n = <span id="result">?</span></div>
        <button onclick="calculate()">计算折射率 n</button>
      </div>
  
      <div class="box">
        <h3>
          A类不确定度
          <span class="tooltip">
            <strong>公式：</strong><br>
            平均值：𝑋̄ = (1/N) ∑Xᵢ<br>
            标准差：S = √(1/(N-1) ∑(Xᵢ - 𝑋̄)²)<br>
            不确定度：δₐ = S / √N
          </span>
        </h3>
      
        <div class="result-box">
          折射率 n₁ = <span id="n1">?</span>，
          n₂ = <span id="n2">?</span>，
          n₃ = <span id="n3">?</span><br>
          A类不确定度：<span id="ua">?</span>
        </div>
      </div>
      
  
      <div class="box">
        <h3>
          B类不确定度
          <span class="tooltip">
            <strong>仪器给定：</strong><br>
            厚度不确定度：Sₜ = 0.004 / √3<br>
            移动距离不确定度：S<sub>Δd</sub> = 0.005 / √3
          </span>
        </h3>
      
        <div class="result-box">
          厚度不确定度：Sₜ = 0.0023<br>
          移动距离不确定度：S<sub>Δd</sub> = 0.0029
        </div>
      </div>
    </div>
      
  
    <!-- 右侧 -->
    <div class="right-panel">
      <div class="box image-box">
        <h3>图像区</h3>
        <img id="preview" src="https://via.placeholder.com/320x240" alt="图像">
      </div>
      <div class="box chart-box">
        <h3>曲线区</h3>
        <div class="curve-selector">
          <label><input type="radio" name="curve" checked> 曲线1</label>
          <label><input type="radio" name="curve"> 曲线2</label>
          <label><input type="radio" name="curve"> 曲线3</label>
        </div>
        <canvas id="myChart"></canvas>
      </div>
    </div>
  </div>


  <script>
    const leds = [1, 2, 3, 4].map(i => document.getElementById('led' + i));
    let isOn = false;
  
    function toggleLEDs() {
      isOn = !isOn;
      leds.forEach(led => led.classList.toggle('on', isOn));
    }
  
    let recentNValues = [];
  
    function calculateDelta() {
      const d1 = parseFloat(document.getElementById('d1').value);
      const d2 = parseFloat(document.getElementById('d2').value);
      if (!isNaN(d1) && !isNaN(d2)) {
        const delta = Math.abs(d2 - d1);
        document.getElementById('delta').innerText = delta.toFixed(4);
      } else {
        alert('请输入有效的 d1 和 d2 值');
      }
    }
  
    function calculate() {
      const deltaTText = document.getElementById('delta').innerText; // Δt
      const deltaDText = document.getElementById('delta_dist').innerText; // Δd

      if (deltaTText !== '?' && deltaDText !== '?') {
        const deltaT = parseFloat(deltaTText);
        const deltaD = parseFloat(deltaDText);

        if (deltaT !== 0) {
          const n = deltaD / deltaT + 1;
          document.getElementById('result').innerText = n.toFixed(4);
          updateNHistory(n);

          const d2 = parseFloat(document.getElementById('d2').value); // x轴仍用厚度 t2
          if (!isNaN(d2)) addNewCurve(d2, n);
        } else {
          alert("Δt 不能为 0");
        }
      } else {
        alert('请先计算 Δt 和 Δd');
      }
    }


    let curveIndex = 1;

    function addNewCurve(d2, n) {
      const color = getRandomColor();
      const label = `测量曲线 ${curveIndex++}`;

      chart.data.datasets.push({
        label: label,
        data: [{ x: d2.toFixed(2), y: n.toFixed(4) }],
        borderColor: color,
        backgroundColor: color,
        fill: false,
        pointBackgroundColor: color,
        pointBorderColor: color,
        tension: 0.1
      });

      chart.update();
    }
    
    function calculateDistanceDelta() {
      const d1 = parseFloat(document.getElementById('d1_dist').value);
      const d2 = parseFloat(document.getElementById('d2_dist').value);
      if (!isNaN(d1) && !isNaN(d2)) {
        const delta = Math.abs(d2 - d1);
        document.getElementById('delta_dist').innerText = delta.toFixed(4);
      } else {
        alert('请输入有效的 d1 和 d2 距离值');
      }
    }

    function getRandomColor() {
      const colors = ['#2196f3', '#f44336', '#4caf50', '#ff9800', '#9c27b0', '#00bcd4'];
      return colors[Math.floor(Math.random() * colors.length)];
    }


    function updateNHistory(n) {
      recentNValues.unshift(n);
      if (recentNValues.length > 3) recentNValues.pop();
      document.getElementById('n1').innerText = recentNValues[0]?.toFixed(4) || '?';
      document.getElementById('n2').innerText = recentNValues[1]?.toFixed(4) || '?';
      document.getElementById('n3').innerText = recentNValues[2]?.toFixed(4) || '?';
  
      if (recentNValues.length >= 2) {
        const mean = recentNValues.reduce((a, b) => a + b, 0) / recentNValues.length;
        const variance = recentNValues.reduce((sum, x) => sum + (x - mean) ** 2, 0) / (recentNValues.length - 1);
        const stdDev = Math.sqrt(variance);
        const uncertainty = stdDev / Math.sqrt(recentNValues.length);
        document.getElementById('ua').innerText = uncertainty.toFixed(4);
      } else {
        document.getElementById('ua').innerText = '?';
      }
    }
  
    // 图表绘制
    const ctx = document.getElementById('myChart').getContext('2d');
    const chart = new Chart(ctx, {
      type: 'line',
      data: {
        datasets: [] // ← 正确，只保留一个 datasets
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: true } // ← 显示图例
       },
       scales: {
          x: {
            type: 'linear', // ← 必须设置为 linear，否则不能使用 x: 厚度数据
            title: { display: true, text: '厚度 d2 (mm)', color: '#333' },
            ticks: { color: '#333' },
           grid: { color: '#eee' }
          },
         y: {
            title: { display: true, text: '折射率 n', color: '#333' },
            beginAtZero: true,
            ticks: { color: '#333' },
            grid: { color: '#eee' }
          }
        }
      }
    });

  
    function updateChart(d2, n) {
      chart.data.labels.push(d2.toFixed(2));
      chart.data.datasets[0].data.push(n);
      if (chart.data.labels.length > 10) {
        chart.data.labels.shift();
        chart.data.datasets[0].data.shift();
      }
      chart.update();
    }
  </script>
    